﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Top.Api.Request;
using Taobao.WangWang.Model;
using Top.Api.Response;

namespace Taobao.WangWang.Common
{
    public class WangWangProcessor
    {
        #region Ctor
         
        public WangWangProcessor(Model.Shop shop)
        {
            Shop = shop;
            TopClient = new Top.Api.DefaultTopClient(ConfigurationManager.AppSettings["ServiceUrl"], shop.AppKey, shop.AppSecret);
            StartDate = DateTime.Today.AddDays(-1);
            EndDate = DateTime.Today.AddDays(-1);
            bool downloadDetailInfo = false;
            Boolean.TryParse(ConfigurationManager.AppSettings["DetailChatInfo"] ?? "false", out downloadDetailInfo);
            DownloadDetailInfo = downloadDetailInfo;

        }

        #endregion

        #region Properties

        public Model.Shop Shop
        {
            get;
            set;
        }

        public Top.Api.DefaultTopClient TopClient
        {
            get;
            private set;
        }

        public DateTime StartDate
        {
            get;
            set;
        }

        public DateTime EndDate
        {
            get;
            set;
        }

        public bool DownloadDetailInfo
        {
            get;
            set;
        }
        #endregion

        #region Process

        public void Process()
        {
            Console.WriteLine(FormatDateInfo("更新店铺：{0}的旺旺记录开始：", Shop.Name));
            UpdateStaffGroups();

            UpdateStaffInfos();
            Console.WriteLine(FormatDateInfo("更新店铺：{0}的旺旺记录结束：", Shop.Name));
        }

        #endregion

        #region Methods

        private string FormatDateInfo(string info,params object[] args)
        {
            info = string.Format(info, args);
            return string.Format("{0} at:{1}",info,DateTime.Now.ToLongTimeString());
        }
        private string FormatTaobaoNick(string nick)
        {
            return string.Format("cntaobao{0}", nick);
        }

        private void UpdateStaffGroups()
        {
            Console.WriteLine(FormatDateInfo("更新客服组和人员信息开始"));
            using (Model.taobaowangwangEntities entities = Model.Util.LoadEntities())
            {
                var groups = (from g in entities.ShopGroups where g.Shop ==Shop.Id select g).ToList();
                groups.ForEach(g => {
                    g.Enabled = false;
                });
                var staffs = (from s in entities.Staffs where s.Shop == Shop.Id select s).ToList();
                staffs.ForEach(s=>s.Enabled=false);

                var allManagers = (from m in entities.ShopManagers where m.Shop == Shop.Id select m).ToList();
                foreach (var manager in allManagers)
                {
                    try
                    {
                        WangwangEserviceGroupmemberGetRequest request = new WangwangEserviceGroupmemberGetRequest();
                        request.ManagerId = FormatTaobaoNick(manager.Nick);
                        WangwangEserviceGroupmemberGetResponse response = TopClient.Execute<WangwangEserviceGroupmemberGetResponse>(request);
                        if (!response.IsError)
                        {
                            foreach (var gm in response.GroupMemberList)
                            {
                                try
                                {
                                    var group = (groups.FirstOrDefault(g => g.Shop == Shop.Id && g.GroupID == gm.GroupId && g.GroupName == g.GroupName && g.Manager == manager.ID));

                                    bool needAdd = group == null;
                                    if (needAdd)
                                        group = new ShopGroup();
                                    group.Enabled = true;
                                    group.GroupID = gm.GroupId;
                                    group.GroupMemberList = gm.MemberList;
                                    group.GroupName = gm.GroupName;
                                    group.Manager = manager.ID;
                                    group.Shop = Shop.Id;
                                    if (needAdd)
                                        entities.ShopGroups.AddObject(group);

                                    entities.SaveChanges();
                                    Console.WriteLine(FormatDateInfo(FormatDateInfo("更新客服组:{0} 的信息",group.GroupName)));

                                    var staff_groups = entities.Staff_Group.Where(sg => sg.Group == group.ID).ToList();
                                    foreach (var sg in staff_groups)
                                    {
                                        entities.Staff_Group.DeleteObject(sg);
                                    }

                                    var members = gm.MemberList.Split(",".ToArray());
                                    foreach (var m in members)
                                    {
                                        Staff staff = staffs.FirstOrDefault(s => s.Shop == Shop.Id && s.Nick == m);
                                        if (staff == null)
                                        {
                                            staff = new Staff();
                                            staff.LastUpdateDate = DateTime.Now;
                                            staff.Nick = m;
                                            staff.Enabled = true;
                                            staff.Shop = Shop.Id;
                                            staff.QueryNick = manager.Nick + "," + m;
                                            entities.Staffs.AddObject(staff);
                                        }
                                        else
                                        {
                                            staff.Enabled = true;
                                            staff.QueryNick = manager.Nick + "," + m;
                                            staff.LastUpdateDate = DateTime.Now;
                                        }
                                        if (entities.Staff_Group.Where(sg => sg.Group == group.ID&&sg.Staff==staff.ID).FirstOrDefault() == null)
                                        {
                                            var sg = entities.Staff_Group.CreateObject();
                                            sg.Group = group.ID;
                                            sg.Staff = staff.ID;
                                            entities.Staff_Group.AddObject(sg);
                                        }
                                        Console.WriteLine(FormatDateInfo(FormatDateInfo("更新客服组:{0} 的成员:{1} ", group.GroupName,staff.Nick)));
                                        entities.SaveChanges();
                                    }
                                }
                                catch (Exception ex)
                                { 
                                }

                            }
                        }
                    }
                    catch (Exception e)
                    {
                    }
                }
            }
            Console.WriteLine(FormatDateInfo("更新客服组和人员信息结束"));
        }

        private void UpdateStaffInfos()
        {
            Console.WriteLine(FormatDateInfo("更新所有客服人员的旺旺记录开始："));
            using (Model.taobaowangwangEntities entities = Model.Util.LoadEntities())
            {
                var allStaffs = (from s in entities.Staffs.Include("StaffStatistics") where s.Shop == Shop.Id select s).ToList();
                foreach (var staff in allStaffs)
                {
                    Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的旺旺记录开始：",staff.Nick));
                    try
                    {
                        staff.LastUpdateDate = DateTime.Now;
                        DateTime fromDate = StartDate;
                        DateTime toDate = EndDate;

                        // OnLineTime
                        UpdateStaffOnlineTime(staff, fromDate, toDate);
                        entities.SaveChanges();

                        //Avg Waiting Time
                        UpdateStaffAvgWaitingTime(staff, fromDate, toDate);
                        entities.SaveChanges();

                        //Receive Num
                        UpdateStaffReceiveNum(staff, fromDate, toDate);
                        entities.SaveChanges();

                        //No Reply Num
                        UpdateStaffNoReplyNum(staff, fromDate, toDate);
                        entities.SaveChanges();

                        // Evaluation
                        UpdateStaffEvaluations(staff, fromDate, toDate);
                        entities.SaveChanges();

                        // Chatpeers
                        UpdateStaffChatpeers(staff, fromDate, toDate);
                        entities.SaveChanges();

                        if (DownloadDetailInfo)
                        {
                            // Chat Logs
                            UpdateStaffChatLogs(staff, fromDate, toDate);
                            entities.SaveChanges();
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                    Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的旺旺记录结束：", staff.Nick));
                }
            }
            Console.WriteLine(FormatDateInfo("更新所有客服人员的旺旺记录结束："));
        }

        private void UpdateStaffOnlineTime(Staff staff, DateTime fromDate, DateTime toDate)
        {
            try
            {
                // OnLineTime
                WangwangEserviceOnlinetimeGetRequest onlinetimeRequest = new WangwangEserviceOnlinetimeGetRequest()
                {
                    StartDate = fromDate,
                    EndDate = toDate,
                    ServiceStaffId = staff.Nick
                };
                WangwangEserviceOnlinetimeGetResponse onlinetimeResponse = TopClient.Execute<WangwangEserviceOnlinetimeGetResponse>(onlinetimeRequest);
                if (!onlinetimeResponse.IsError)
                {
                    foreach (var onlineTimesListOnDays in onlinetimeResponse.OnlineTimesListOnDays)
                    {
                        try
                        {
                            var date = Convert.ToDateTime(onlineTimesListOnDays.OnlineDate);
                            var staffStatistic = staff.StaffStatistics.Where(ss => ss.Date == date).FirstOrDefault();
                            if (staffStatistic == null)
                            {
                                staffStatistic = new StaffStatistic();
                                staffStatistic.Staff = staff.ID;
                                staffStatistic.Date = date;
                                staff.StaffStatistics.Add(staffStatistic);
                            }
                            if (onlineTimesListOnDays.OnlineTimeByIds.Count > 0)
                            {
                                staffStatistic.OnlineTime = onlineTimesListOnDays.OnlineTimeByIds[0].OnlineTimes;
                            }

                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的在线时间成功", staff.Nick));
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的在线时间失败", staff.Nick));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的在线时间失败", staff.Nick));
            }
        }

        private void UpdateStaffAvgWaitingTime(Staff staff, DateTime fromDate, DateTime toDate)
        {
            try
            {
                //Avg Waiting Time
                WangwangEserviceAvgwaittimeGetRequest avgWaitingtimeRequest = new WangwangEserviceAvgwaittimeGetRequest()
                {
                    StartDate = fromDate,
                    EndDate = toDate,
                    ServiceStaffId = staff.Nick
                };
                WangwangEserviceAvgwaittimeGetResponse avgWaitingtimeResponse = TopClient.Execute<WangwangEserviceAvgwaittimeGetResponse>(avgWaitingtimeRequest);
                if (!avgWaitingtimeResponse.IsError)
                {
                    foreach (var waitingTimeListOnDays in avgWaitingtimeResponse.WaitingTimeListOnDays)
                    {
                        try
                        {
                            var date = Convert.ToDateTime(waitingTimeListOnDays.WaitingDate);
                            var staffStatistic = staff.StaffStatistics.Where(ss => ss.Date == date).FirstOrDefault();
                            if (staffStatistic == null)
                            {
                                staffStatistic = new StaffStatistic();
                                staffStatistic.Staff = staff.ID;
                                staffStatistic.Date = date;
                                staff.StaffStatistics.Add(staffStatistic);
                            }
                            if (waitingTimeListOnDays.WaitingTimeByIds.Count > 0)
                            {
                                staffStatistic.AvgWaitingTimes = waitingTimeListOnDays.WaitingTimeByIds[0].AvgWaitingTimes;
                            }
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的平均等待时间成功", staff.Nick));
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的平均等待时间失败", staff.Nick));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的平均等待时间失败", staff.Nick));
            }
            
        }
        
        private void UpdateStaffReceiveNum(Staff staff, DateTime fromDate, DateTime toDate)
        {
            try
            {
                //Receive Num   

                WangwangEserviceReceivenumGetRequest receiveNumRequest = new WangwangEserviceReceivenumGetRequest()
                {
                    StartDate = fromDate,
                    EndDate = toDate,
                    ServiceStaffId = staff.Nick
                };
                WangwangEserviceReceivenumGetResponse receiverNumResponse = TopClient.Execute<WangwangEserviceReceivenumGetResponse>(receiveNumRequest);
                if (!receiverNumResponse.IsError)
                {
                    foreach (var replyStatListOnDays in receiverNumResponse.ReplyStatListOnDays)
                    {
                        try
                        {
                            var date = Convert.ToDateTime(replyStatListOnDays.ReplyDate);
                            var staffStatistic = staff.StaffStatistics.Where(ss => ss.Date == date).FirstOrDefault();
                            if (staffStatistic == null)
                            {
                                staffStatistic = new StaffStatistic();
                                staffStatistic.Staff = staff.ID;
                                staffStatistic.Date = date;
                                staff.StaffStatistics.Add(staffStatistic);
                            }
                            if (replyStatListOnDays.ReplyStatByIds.Count > 0)
                            {
                                staffStatistic.AvgWaitingTimes = replyStatListOnDays.ReplyStatByIds[0].ReplyNum;
                            }
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的服务客户数成功", staff.Nick));
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的服务客户数失败", staff.Nick));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的服务客户数失败", staff.Nick));
            }
        }

        private void UpdateStaffNoReplyNum(Staff staff, DateTime fromDate, DateTime toDate)
        {
            try
            {
                //Non Reply Num

                WangwangEserviceNoreplynumGetRequest nonReplyRequest = new WangwangEserviceNoreplynumGetRequest()
                {
                    StartDate = fromDate,
                    EndDate = toDate,
                    ServiceStaffId = staff.Nick
                };
                WangwangEserviceNoreplynumGetResponse noReplyResponse = TopClient.Execute<WangwangEserviceNoreplynumGetResponse>(nonReplyRequest);
                if (!noReplyResponse.IsError)
                {
                    foreach (var nonReplyStatOnDays in noReplyResponse.NonReplyStatOnDays)
                    {
                        try
                        {
                            var date = Convert.ToDateTime(nonReplyStatOnDays.NonreplyDate);
                            var staffStatistic = staff.StaffStatistics.Where(ss => ss.Date == date).FirstOrDefault();
                            if (staffStatistic == null)
                            {
                                staffStatistic = new StaffStatistic();
                                staffStatistic.Staff = staff.ID;
                                staffStatistic.Date = date;
                                staff.StaffStatistics.Add(staffStatistic);
                            }
                            if (nonReplyStatOnDays.NonreplyStatByIds.Count > 0)
                            {
                                staffStatistic.NonReplyNum = nonReplyStatOnDays.NonreplyStatByIds[0].NonReplyNum;
                                staffStatistic.NonReplyCustomIDs = nonReplyStatOnDays.NonreplyStatByIds[0].NonReplyCustomId;
                            }
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的未回复客户数成功", staff.Nick));
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的未回复客户数失败", staff.Nick));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的未回复客户数失败", staff.Nick));
            }

        }

        private void UpdateStaffEvaluations(Staff staff, DateTime fromDate, DateTime toDate)
        {
            try
            {
                // Staff Evaluation

                WangwangEserviceEvaluationGetRequest evaluationRequest = new WangwangEserviceEvaluationGetRequest()
                {
                    StartDate = fromDate,
                    EndDate = toDate,
                    ServiceStaffId = staff.Nick
                };
                WangwangEserviceEvaluationGetResponse evaluationResponse = TopClient.Execute<WangwangEserviceEvaluationGetResponse>(evaluationRequest);
                if (!evaluationResponse.IsError)
                {
                    foreach (var staffEvalStatOnDays in evaluationResponse.StaffEvalStatOnDays)
                    {
                        try
                        {
                            var date = Convert.ToDateTime(staffEvalStatOnDays.EvalDate);
                            var staffStatistic = staff.StaffStatistics.Where(ss => ss.Date == date).FirstOrDefault();
                            if (staffStatistic == null)
                            {
                                staffStatistic = new StaffStatistic();
                                staffStatistic.Staff = staff.ID;
                                staffStatistic.Date = date;
                                staff.StaffStatistics.Add(staffStatistic);
                            }
                            if (staffEvalStatOnDays.StaffEvalStatByIds.Count > 0)
                            {
                                staffStatistic.StaffEvaluations.Clear();
                                foreach (var eva in staffEvalStatOnDays.StaffEvalStatByIds[0].Evaluations)
                                {
                                    int num = 0;
                                    Int32.TryParse(eva.EvaluationNum, out num);
                                    var evaluation = new StaffEvaluation();
                                    evaluation.Count = num;
                                    evaluation.StatisticsID = staffStatistic.ID;
                                    evaluation.EveluationType = eva.EvaluationName;
                                    staffStatistic.StaffEvaluations.Add(evaluation);
                                }
                            }
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的客户评价成功", staff.Nick)); 
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的客户评价成功", staff.Nick)); 
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的客户评价失败", staff.Nick)); 
            }
        }

        private void UpdateStaffChatpeers(Staff staff, DateTime fromDate, DateTime toDate)
        {
            try
            {
                //Chatpeers

                WangwangEserviceChatpeersGetRequest chatpeersRequest = new WangwangEserviceChatpeersGetRequest()
                {
                    StartDate = fromDate.ToShortDateString(),
                    EndDate = toDate.ToShortDateString(),
                    ChatId = staff.Nick
                };
                WangwangEserviceChatpeersGetResponse chatpeersResponse = TopClient.Execute<WangwangEserviceChatpeersGetResponse>(chatpeersRequest);
                if (!chatpeersResponse.IsError && chatpeersResponse.Ret == 10000)
                {
                    foreach (var chatpeer in chatpeersResponse.Chatpeers)
                    {
                        try
                        {
                            var date = Convert.ToDateTime(chatpeer.Date);
                            var staffStatistic = staff.StaffStatistics.Where(ss => ss.Date == date).FirstOrDefault();
                            if (staffStatistic == null)
                            {
                                staffStatistic = new StaffStatistic();
                                staffStatistic.Staff = staff.ID;
                                staffStatistic.Date = date;
                                staff.StaffStatistics.Add(staffStatistic);
                            }
                            var chatpeerInDb = staffStatistic.StaffChatpeers.Where(c => c.ChatpeerUID == chatpeer.Uid).FirstOrDefault();
                            if (chatpeerInDb == null)
                            {
                                chatpeerInDb = new StaffChatpeer();
                                chatpeerInDb.ChatpeerUID = chatpeer.Uid;
                                chatpeerInDb.ChatDate = date;
                                staffStatistic.StaffChatpeers.Add(chatpeerInDb);
                            }
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的聊天客户对象成功", staff.Nick)); 
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的聊天客户对象失败", staff.Nick)); 
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的聊天客户对象失败", staff.Nick));  
            }
        }

        private void UpdateStaffChatLogs(Staff staff, DateTime fromDate, DateTime toDate)
        {
            try
            {
                // 
                var allChatpeers = GetChatpeers(staff, fromDate, toDate);
                foreach (var chatpeer in allChatpeers)
                {
                    try
                    {
                        WangwangEserviceChatlogGetRequest sentChatlogRequest = new WangwangEserviceChatlogGetRequest()
                        {
                            FromId = staff.Nick,
                            ToId = chatpeer.Uid,
                            EndDate = chatpeer.Date,
                            StartDate = chatpeer.Date
                        };
                        WangwangEserviceChatlogGetResponse sentChatlogResponse = TopClient.Execute<WangwangEserviceChatlogGetResponse>(sentChatlogRequest);

                        WangwangEserviceChatlogGetRequest receivedChatlogRequest = new WangwangEserviceChatlogGetRequest()
                        {
                            ToId = staff.Nick,
                            FromId = chatpeer.Uid,
                            EndDate = chatpeer.Date,
                            StartDate = chatpeer.Date
                        };
                        WangwangEserviceChatlogGetResponse receivedChatlogResponse = TopClient.Execute<WangwangEserviceChatlogGetResponse>(receivedChatlogRequest);

                        var allMsgs = new List<Top.Api.Domain.Msg>();
                        if (!sentChatlogResponse.IsError && sentChatlogResponse.Ret == 10000)
                        {
                            allMsgs.AddRange(sentChatlogResponse.Msgs);
                        }
                        if (!receivedChatlogResponse.IsError && receivedChatlogResponse.Ret == 10000)
                        {
                            allMsgs.AddRange(receivedChatlogResponse.Msgs);
                        }
                        foreach (var msg in allMsgs)
                        {
                            var date = Convert.ToDateTime(chatpeer.Date);
                            var staffStatistics = staff.StaffStatistics.Where(ss => ss.Date == date).FirstOrDefault();
                            if (staffStatistics == null)
                            {
                                staffStatistics = new StaffStatistic();
                                staffStatistics.Date = date;
                                staffStatistics.Staff = staff.ID;
                                staff.StaffStatistics.Add(staffStatistics);
                            }
                            var chatlog = staffStatistics.StaffChatLogs.Where(sl => sl.ChatpeerNick == chatpeer.Uid
                                && sl.StaffNick == staff.Nick
                                && sl.Content == msg.Content
                                && sl.Direction == msg.Direction
                                && sl.Time == Convert.ToDateTime(msg.Time)).FirstOrDefault();
                            if (chatlog == null)
                            {
                                chatlog = new StaffChatLog();
                                chatlog.Time = Convert.ToDateTime(msg.Time);
                                chatlog.StaffNick = staff.Nick;
                                chatlog.Direction = msg.Direction;
                                chatlog.Content = msg.Content;
                                chatlog.ChatpeerNick = chatpeer.Uid;
                                staffStatistics.StaffChatLogs.Add(chatlog);
                            }
                        }
                        Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的详细聊天记录成功", staff.Nick));  

                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的详细聊天记录失败", staff.Nick));  
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(FormatDateInfo("更新客服人员：{0} 的详细聊天记录失败", staff.Nick));  
            }
        }

        private List<Top.Api.Domain.Chatpeer> GetChatpeers(Staff staff, DateTime fromDate, DateTime toDate)
        { 
            List<Top.Api.Domain.Chatpeer> queryChatpeers = new List<Top.Api.Domain.Chatpeer>();

            WangwangEserviceChatpeersGetRequest chatpeersRequest = new WangwangEserviceChatpeersGetRequest()
            {
                StartDate = fromDate.ToShortDateString(),
                EndDate = toDate.ToShortDateString(),
                ChatId= staff.Nick
            };
            WangwangEserviceChatpeersGetResponse chatpeersResponse = TopClient.Execute<WangwangEserviceChatpeersGetResponse>(chatpeersRequest);
            if (!chatpeersResponse.IsError && chatpeersResponse.Ret == 10000)
            {
                queryChatpeers = chatpeersResponse.Chatpeers;
            }
            return queryChatpeers;
        }
        #endregion
    }
}
